package homework.valid.validators;

import homework.valid.validators.parser.ValueParser;

import java.util.ArrayList;
import java.util.List;

public class ValidateChain implements Validator {

    private ArrayList<BaseValidator> valids;
    private ValueParser parser;

    public ValidateChain(ValueParser p, BaseValidator... valids) {
        this(p);
        for(BaseValidator v: valids)
            addValidator(v);
    }

    public ValidateChain(ValueParser p) {
        parser = p;
        this.valids = new ArrayList<BaseValidator>();
    }

    public ValidateChain() {
        this(new ValueParser(null) {
            @Override
            public Object parse(Object v) {
                return v;
            }
        });
    }

    @Override
    public boolean isValid(Object v) {
        try {
            v = parse(v);
        } catch (Exception e) {
            return false;
        }
        if(v instanceof List) {
            for(Validator valid: valids) {
                for (Object each : (List)v) {
                    if(!valid.isValid(each))
                        return false;
                }
            }
        } else {
            for(Validator valid: valids) {
                if(!valid.isValid(v))
                    return false;
            }
        }
        return true;
    }

    public void addValidator(BaseValidator v) {
        this.valids.add(v);
    }

    public void removeValidator(BaseValidator v) {
        this.valids.remove(v);
    }

    public void removeValidator(int i) {
        this.valids.remove(i);
    }

    public String getErrorMessage(Object v) {
        try {
            v = parse(v);
        } catch (Exception e) {
            String msg = parser.getMessage();
            if(msg == null)
                msg = e.getMessage();
            return msg;
        }
        if(v instanceof List) {
            for(BaseValidator valid: valids) {
                for(Object each: (List)v) {
                    if(!valid.isValid(each))
                        return valid.getMessage();
                }
            }
        } else {
            for(BaseValidator valid: valids) {
                if(!valid.isValid(v))
                    return valid.getMessage();
            }
        }
        return null;
    }

    public String[] getErrorMessages(Object v) {
        ArrayList<String> messages = new ArrayList<String>();
        try {
            v = parse(v);
        } catch (Exception e) {
            String msg = parser.getMessage();
            if(msg == null)
                msg = e.getMessage();
            messages.add(msg);
        }
        if(v instanceof List) {
            for(BaseValidator valid: valids) {
                for(Object each: (List)v) {
                    if(!valid.isValid(each))
                        messages.add(valid.getMessage());
                }
            }
        } else {
            for (BaseValidator valid: valids) {
                if(!valid.isValid(v))
                    messages.add(valid.getMessage());
            }
        }
        return messages.toArray(new String[messages.size()]);
    }

    public Object parse(Object v) throws Exception {
        return parser.parse(v);
    }
}
